package com.qf.day31_boot.controller;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.crypto.digest.DigestUtil;

import com.qf.day31_boot.entity.User;
import com.qf.day31_boot.service.UserService;
import com.qf.day31_boot.utils.Constants;
import com.qf.day31_boot.vo.vo.ResultVo;
import com.qf.day31_boot.vo.vo.TableVo;
import com.qf.day31_boot.vo.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/user")
@Slf4j  // 添加该注解后，可以使用 log对象进行日志的打印
public class UserController {

    @Autowired
    private UserService userService;

    @Value("${pic.dir")
    private String picDir;

    @PostMapping("/login")
    public ResultVo login(String username, String password, String captcha,
                          String autologin, HttpServletResponse response, HttpSession session) {

        log.info("username={},password={},captcha={}", username, password, captcha);

        //1. 处理验证码是否正确
        final LineCaptcha sessionCaptcha = (LineCaptcha) session.getAttribute(Constants.HUTOOL_CAPTCHA);

        if (!sessionCaptcha.verify(captcha)) {
            return new ResultVo(Constants.FAIL_CODE, "验证码错误");
        }

        //2. 调用service层的方法进行登录验证
        User user = userService.login(username, password);
        log.info("调用service层方法校验用户密码，返回的user对象={}", user);

        //3. 如果user不为null，则代表登录成功，如果user为null，则登录失败
        if (user != null) {

            // 如果用户登录成功，把user对象存入session
            session.setAttribute(Constants.SESSION_USER_KEY, user);

            if ("on".equals(autologin)) {
                // 生成用于免登陆的cookie，cookie中的信息包含用户名和密码
                final String md5password = DigestUtil.md5Hex(password);
                String cookievalue = username + "-" + md5password;
                final Cookie cookie = new Cookie(Constants.USER_TOKEN, cookievalue);
                cookie.setPath("/");    // 设置cookie为该域的顶级cookie
                cookie.setMaxAge(60 * 60 * 24 * 14);  // 两周有效期
                log.debug("用户设置免登陆，cookie={}", cookievalue);
                response.addCookie(cookie);
            }

            return new ResultVo(Constants.SUCCESS_CODE, "登录成功");

        } else {
            return new ResultVo(Constants.FAIL_CODE, "登陆失败");
        }


    }

    /**
     * 用户注册接口，该接口接收的是文件上传请求
     *
     * @param userVo
     * @param session
     * @return
     */
    @PostMapping("/regist")
    public ResultVo regist(UserVo userVo, HttpSession session) throws IOException {

        log.info("用户注册请求处理，userVo={}", userVo);

        //1. 处理验证码是否正确
        final String sessionCaptcha = (String) session.getAttribute("captcha");

        if (!sessionCaptcha.equals(userVo.getCaptcha())) {
            return new ResultVo(Constants.FAIL_CODE, "验证码错误");
        }

        //2. 调用service层方法完成注册的业务逻辑
        final String realPath = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);

        ResultVo resultVo = userService.regist(userVo, realPath);

        return resultVo;
    }

    /**
     * 获取登录用户的用户名
     *
     * @param session
     * @return
     */
    @GetMapping("/currentuser")
    public ResultVo getCurrentUser(HttpSession session) {

        //从session中获取当前登录用户的用户名
        final User user = (User) session.getAttribute(Constants.SESSION_USER_KEY);
        log.debug("获取当前登录用户，user={}", user);
        if (user != null) {

            return new ResultVo(Constants.SUCCESS_CODE, "获取登录用户成功", user.getName());
        } else {
            return new ResultVo(Constants.FAIL_CODE, "获取登录用户失败");
        }

    }

    /**
     * 获取当前登录用户的头像
     */
    @GetMapping("/pic")
    public void getPic(HttpSession session, HttpServletResponse response) throws IOException {
        final User user = (User) session.getAttribute(Constants.SESSION_USER_KEY);
        if (user != null) {

            final String photoPath = user.getPhotopath();

            final String fileDir = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);

            final String finalFilePath = fileDir + File.separator + photoPath;
            log.debug("获取登录用户的头像，文件路径为={}", finalFilePath);
            // 把图片文件响应给浏览器
            IOUtils.copy(new FileInputStream(finalFilePath), response.getOutputStream());

        } else {

            return;

        }
    }

    @GetMapping("/checkusername")
    public ResultVo checkusername(String username) {
        // 调用service层检查用户名是否存在
        ResultVo resultVo = userService.checkUserName(username);
        log.debug("检测用户名是否存在，username={},resultVo={}", username, resultVo);
        return resultVo;

    }

    /**
     * 用户数据表格分页查询接口
     *
     * @param page  页号
     * @param limit 页大小
     * @return
     */
    @GetMapping("/getAllUsers")
    public TableVo<User> getAllUser(Integer page, Integer limit) {

        log.debug("分页查询用户,page={},limit={}", page, limit);

        TableVo tableVo = userService.getAllUsersByPage(page, limit);

        log.debug("查询到的结果为，tableVo={}", tableVo);

        return tableVo;

    }

    /**
     * 使用分页插件实现
     *
     * @param page
     * @param limit
     * @return
     */
    @GetMapping("/getUserByPageHelper")
    public TableVo<User> getUserByPageHelper(Integer page, Integer limit) {

        log.debug("分页查询用户,page={},limit={}", page, limit);

        TableVo tableVo = userService.getAllUsersByPage(page, limit);

        log.debug("查询到的结果为，tableVo={}", tableVo);

        return tableVo;

    }

    /**
     * 添加用户接口
     *
     * @return
     */
    @PostMapping("/add")
    public ResultVo add(User user) {

        log.debug("接收到参数，user={}", user);

        ResultVo resultVo = userService.addUser(user);
        log.debug("新增结果为：resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * @param idarray
     * @return
     * @RequestParam 这个注解可以处理方法参数名和请求参数名不一致的情况
     */
    @RequestMapping("/del")
    public ResultVo del(@RequestParam("ids") List<Integer> idarray) {

        log.debug("收到参数：ids={}", idarray);

        ResultVo resultVo = userService.deleteUserByIds(idarray);

        log.debug("删除结果为：resultVo={}", resultVo);
        return resultVo;
    }

    @PostMapping("/update")
    public ResultVo update(User user) {

        log.info("收到参数，userVo={}", user);
        ResultVo resultVo = userService.updateUser(user);
        log.debug("修改结果为：resultVo={}", resultVo);
        return resultVo;
    }

    /**
     * @param page
     * @param limit
     * @param userVo
     * @return
     */
    @GetMapping("/getUsersByCondition")
    public TableVo<User> getUsersByCondition(Integer page, Integer limit, UserVo userVo) {

        log.debug("收到参数,page={},limit={},userVo={}", page, limit, userVo);

        TableVo<User> result = userService.getUsersByCondition(page, limit, userVo);

        return result;
    }

    @GetMapping("/export")
    public ResultVo export(HttpSession session) throws IOException {

        //1. 调用service层的方法进行数据导出，生成文件
        /*final String realPath = session.getServletContext().getRealPath(Constants.UPLOAD_PATH);
        ResultVo resultVo = userService.export(realPath);*/
        String filename = userService.export();

        //2.返回包含文件名的 resultVo
        return new ResultVo(Constants.SUCCESS_CODE, "导出文件成功", filename);

    }

}
